package com.frank.oj.service.entity.judge.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frank.model.entity.contest.ContestRecord;
import com.frank.model.entity.judge.Judge;
import com.frank.model.entity.problem.Problem;
import com.frank.oj.constant.Constants;
import com.frank.oj.mapper.JudgeMapper;
import com.frank.oj.mapper.ProblemMapper;
import com.frank.oj.model.vo.ContestScrollBoardSubmissionVO;
import com.frank.oj.model.vo.JudgeVO;
import com.frank.oj.model.vo.ProblemCountVO;
import com.frank.oj.service.entity.contest.ContestRecordEntityService;
import com.frank.oj.service.entity.judge.JudgeEntityService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author frank
 * @Date 2024/1/25
 */
@Service
public class JudgeEntityServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements JudgeEntityService {

    @Resource
    private JudgeMapper judgeMapper;
    @Resource
    private ProblemMapper problemMapper;
    @Resource
    private ContestRecordEntityService contestRecordEntityService;

    @Override
    public List<ProblemCountVO> getProblemListCount(List<Long> pidList) {
        return judgeMapper.getProblemListCount(pidList);
    }

    @Override
    public IPage<JudgeVO> getCommonJudgeList(Integer limit, Integer currentPage, String uid, String searchPid, Integer status, String username, Boolean completeProblemID, Long gid) {

        Page<JudgeVO> page = new Page<>(currentPage, limit);
        // 当前页码的提交数据
        IPage<JudgeVO> commonJudgeList = judgeMapper.getCommonJudgeList(page, searchPid, status, username, uid, completeProblemID, gid);

        // 获取判题的题目标题
        List<JudgeVO> judges = commonJudgeList.getRecords();
        if (!CollectionUtils.isEmpty(judges)) {
            List<Long> pids = judges.stream().map(JudgeVO::getPid).collect(Collectors.toList());

            LambdaQueryWrapper<Problem> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(Problem::getId, Problem::getTitle)
                    .in(Problem::getId, pids);
            List<Problem> problemList = problemMapper.selectList(queryWrapper);

            Map<Long, String> map = new HashMap<>(limit);
            for (JudgeVO judge : judges) {
                judge.setTitle(getProblemTitleByPid(judge.getPid(), problemList, map));
            }
        }
        // 可省略，对象引用传递，修改judge就是修改commonJudgeList中的值
        //commonJudgeList.setRecords(judges);
        return commonJudgeList;
    }

    @Override
    public int getTodayJudgeNum() {

        return judgeMapper.getTodayJudgeNum();
    }

    @Override
    public ProblemCountVO getProblemCount(Long pid, Long gid) {
        return judgeMapper.getProblemCount(pid, gid);
    }

    @Override
    public ProblemCountVO getContestProblemCount(Long pid, Long cpid, Long cid, Date startTime, Date sealRankTime, List<String> adminList) {
        return judgeMapper.getContestProblemCount(pid, cpid, cid, startTime, sealRankTime, adminList);
    }

    @Override
    public IPage<JudgeVO> getContestJudgeList(Integer limit, Integer currentPage, String displayId, Long cid, Integer status, String username, String uid, Boolean beforeContestSubmit, String rule, Date startTime, Date sealRankTime, String sealTimeUid, Boolean completeProblemID) {
        Page<JudgeVO> page = new Page<>(currentPage, limit);
        return judgeMapper.getContestJudgeList(page, displayId, cid, status, username, uid, beforeContestSubmit,
                rule, startTime, sealRankTime, sealTimeUid, completeProblemID);
    }

    @Override
    public void failToUseRedisPublishJudge(Long submitId, Long pid, boolean isContest) {
        UpdateWrapper<Judge> judgeUpdateWrapper = new UpdateWrapper<>();
        judgeUpdateWrapper.eq("submit_id", submitId)
                .set("error_message", "The something has gone wrong with the data Backup server. Please report this to administrator.")
                .set("status", Constants.Judge.STATUS_SYSTEM_ERROR.getStatus());
        judgeMapper.update(null, judgeUpdateWrapper);
        // 更新contest_record表
        if (isContest) {
            UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("submit_id", submitId)
                    .set("first_blood", false)
                    .set("status", Constants.Contest.RECORD_NOT_AC_NOT_PENALTY.getCode());
            contestRecordEntityService.update(updateWrapper);
        }

    }

    @Override
    public List<ContestScrollBoardSubmissionVO> getContestScrollBoardSubmission(Long cid, List<String> removeUidList) {
        return judgeMapper.getContestScrollBoardSubmission(cid, removeUidList);
    }

    private String getProblemTitleByPid(Long pid, List<Problem> problemList, Map<Long, String> map) {

        String title = map.get(pid);
        if (title != null) {
            return title;
        }
        for (Problem problem : problemList) {
            if (problem.getId().equals(pid)) {
                map.put(pid, problem.getTitle());
                return problem.getTitle();
            }
        }
        return "[题目未知]";
    }
}
